package org.dtrd.modules.shop.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.util.DateUtils;
import org.dtrd.common.util.RedisUtil;
import org.dtrd.config.pay.PayConfig;
import org.dtrd.config.pay.PayConstant.OrderStatus;
import org.dtrd.config.pay.PayConstant.PayStatus;
import org.dtrd.config.pay.PayConstant.PayType;
import org.dtrd.config.system.SystemState.ResponseState;
import org.dtrd.config.wechat.api.impl.WechatApi;
import org.dtrd.config.wechat.config.WechatUtil;
import org.dtrd.config.wechat.config.wechatpay.PayScene;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninRecordService;
import org.dtrd.modules.patient.entity.bean.PatientInfo;
import org.dtrd.modules.patient.entity.po.DtrdEntRdPatient;
import org.dtrd.modules.patient.service.IDtrdEntRdPatientService;
import org.dtrd.modules.shop.entity.po.DtrdEntShcRdOrder;
import org.dtrd.modules.shop.entity.request.WechatPrePayRequest;
import org.dtrd.modules.shop.service.IDtrdEntShcRdOrderService;
import org.dtrd.modules.shop.service.IKingdeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Date;

/**
 * 支付相关
 *
 * @author 萧
 * @date:2021-12-20 5:10 下午
 **/
@Slf4j
@RestController
@RequestMapping("/901/01")
@ApiSort(90101)
@Api(tags = "支付相关接口")
public class PayController extends BaseController {

    @Autowired
    private IDtrdEntRdPatientService dtrdEntRdPatientService;
    @Autowired
    private IKingdeeService kingdeeService;

    @Autowired
    private WechatApi wechatApi;

    @Autowired
    private IDtrdEntShcRdOrderService orderService;

    @Resource
    @Lazy
    private RedisUtil redisUtil;

    @ApiOperation("微信预下单")
    @PostMapping(path = {"/9010101/{path}"})
    public Result<?> prePay(@PathVariable @ApiParam(value = "请求场景H5/APP等", example = "APP支付：app；/公众号/H5支付：h5；/JSAPI/小程序支付：jsapi；/原生支付、扫码支付:native") String path,
                            @RequestBody WechatPrePayRequest prePayRequest
            , HttpServletRequest request) {
        PayScene scene = PayScene.findMatchScene(path);
        if (scene == null) {
            return error(ResponseState.STATE_PARAMS_ERROR);
        }
        // TODO 待补充订单有效期
        String orderNo = prePayRequest.getOrderNo();
        DtrdEntShcRdOrder orderInfo;
        String key = prePayRequest.getPatientId() + prePayRequest.getServiceId() + prePayRequest.getServiceSpec() + prePayRequest.getOrderType();
        if (orderNo == null) {
//             redisUtil.get(prePayRequest.getPatientId()+"" + prePayRequest.getServiceId() + prePayRequest.getOrderType());
            orderInfo = orderService.createServiceOrder(prePayRequest.getPatientId(), prePayRequest.getServiceId(), prePayRequest.getServiceSpec(), prePayRequest.getOrderType());
            log.info("PayController.prePay.[path, prePayRequest, request] orderNo is null orderInfo = " + orderInfo);
            if (orderInfo == null) {
                return error(ResponseState.STATE_OPERATION_FAILURE);
            }
            orderNo = orderInfo.getDataId();
            redisUtil.set(key, orderNo, PayConfig.getValidTime());
        } else {
            Object o = redisUtil.get(key);
            long expire = redisUtil.getExpire(key);
            log.info("PayController.prePay.[path, prePayRequest, request] o=" + o + "; expire=" + expire);
            orderInfo = orderService.getById(orderNo);
        }
        // TODO 商品订单关系表存数据
        // TODO 记录收货地址
        // TODO 收货地址同步到金蝶客户系统
        log.info("PayController.prePay.[path, prePayRequest, request] orderInfo =" + orderInfo);
        String pay = wechatApi.prePay(scene, prePayRequest.getPatientId(), prePayRequest.getOpenId(), orderNo, orderInfo.getOrderInfoSum(), orderInfo.getOrderInfoTitle(), prePayRequest.getSceneInfo(), request);
        return StrUtil.isBlank(pay) ? error(ResponseState.STATE_OPERATION_FAILURE) : Result.OK(pay);
    }

    @ApiOperation("微信支付回调")
    @RequestMapping(value = "/9010102", method = {RequestMethod.POST, RequestMethod.GET})
    public Result<?> onWechatPayCallBack(@RequestBody(required = false) JSONObject object) {
        log.info("PayController.onWechatPayCallBack.[object] object " + object);
        JSONObject resource = object.getJSONObject("resource");
        AesUtil aesUtil = new AesUtil(PayConfig.getWechatPayConfig().getPrivateKeyV3().getBytes(StandardCharsets.UTF_8));
        try {
            String decrypt = aesUtil.decryptToString(
                    resource.getString("associated_data").getBytes(StandardCharsets.UTF_8),
                    resource.getString("nonce").getBytes(StandardCharsets.UTF_8),
                    resource.getString("ciphertext")
            );
            log.info("PayController.onWechatPayCallBack.[object] decrypt  = " + decrypt);
            JSONObject object1 = JSONObject.parseObject(decrypt);
            String orderDataId = object1.getString("out_trade_no");
            JSONObject attach = object1.getJSONObject("attach");
            orderService.updateOrderStatus(orderDataId, attach.getIntValue("userId"), PayStatus.PAYED.getState(), OrderStatus.PAYED.getState(), PayType.WECHATPAY.getType(), object1.getString("transaction_id"));
//            {"mchid":"1622632141","appid":"wx0c5e5163287faad8",
//                    "out_trade_no":"39d15eddf1da68a28a0a2bde24e5cc93",
//                    "transaction_id":"4200001442202206060862948359",
//                    "trade_type":"JSAPI","trade_state":"SUCCESS",
//                    "trade_state_desc":"支付成功",
//                    "bank_type":"NJCB_CREDIT",
//                    "attach":"{\"attach\":\"jsapi\",\"userId\":170}",
//                    "success_time":"2022-06-06T17:09:16+08:00",
//                    "payer":{"openid":"oxreB5Pe_1XJRSmaRoVo-X_w"},
//                "amount":{"total":1,"payer_total":1,"currency":"CNY","payer_currency":"CNY"}}

            // 订单信息同步到金蝶销售订单
            JSONObject request = new JSONObject();
            request.put("billsource", "MINA");
            request.put("billdate", DateUtils.formatDate(new Date(), DateUtils.date_sdf.get().toPattern()));

            // 获取当前患者的金蝶客户id，如果患者未同步到金蝶，先进行患者信息上传再进行订单数据上传
            Integer userId = attach.getIntValue("userId");
            // 获取用户信息
            PatientInfo patient = dtrdEntRdPatientService.selectByPatientId(userId);
            // TODO 获取金蝶商品信息， 从商品订单关联表中获取
            // TODO 获取收货地址信息
//            String kingdeeId = patient.getKingdeeCustomerId();
//            if (kingdeeId.equals("")) {
//                // TODO 同步患者信息到金蝶客户系统
//                dtrdEntRdPatientService.syncPatientToKingdeeCRM(patient);
//            }




            request.put("customerid_id", patient.getKingdeeCustomerId());
            JSONArray materialEntity = new JSONArray();
            JSONObject material = new JSONObject();

            material.put("materialid_id", "1431349996371836928");
            material.put("qty", 1);
            material.put("unit_id", 1);
            material.put("price", 99);
            material.put("taxprice", 99);
            material.put("is_free", false);
            materialEntity.add(0, material);
            request.put("material_entity", materialEntity);
            request.put("ignorewarn", true);
            JSONObject addCustomer = kingdeeService.queryKingdeeApi("/jdy/sal/sal_order_save", request);


        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return Result.OK();
    }

    @ApiOperation("Native 支付回调")
    @PostMapping("/1010604")
    public Result<?> getApi() {
        return Result.OK();
    }

}
